package d2_reflect;

import org.junit.Test;

import java.lang.reflect.Method;

/**
 * 目标: 掌握获取类的成员方法, 并对其进行性操作
 */
public class Test4Method {
    @Test//                        这个异常,会直接抛的虚拟机
    public void testGetMethods() throws Exception {
        //1、反射第一步: 先得到Class对象
        Class d = Dog.class;

        //2、获取类的全部成员方法
        Method[] methods = d.getDeclaredMethods();


        //3、遍历这个数组中的每一个方法
        for (Method method : methods) {
            System.out.println(method.getName() +
                    "====>"
                    + method.getParameterCount());
        }

        //4、获取某个方法的对象
        //两个参数 1、方法名 2、参数类型
        Method eat = d.getDeclaredMethod("eat");

        System.out.println(eat.getName() +
                "===>" +
                eat.getParameterCount()+
                "===>" +
                eat.getReturnType());
        //唤醒哪个对象中的方法执行
        Dog dog = new Dog();
        //解释: 思想:先找到方法,然后再找对象来跑它,然后再传参数,得到返回结果
        Object invoke = eat.invoke(dog);//没有结果返回null
        System.out.println(invoke);
        System.out.println("---------------------");
        Method eat1 = d.getDeclaredMethod("eat", String.class);
        //由于是private修饰,所以要进行暴力反射->否则报错
        eat1.setAccessible(true);


       /* System.out.println(eat1.getName() +
                "===>" +
                eat1.getParameterCount()+
                "===>" +
                eat1.getReturnType());*/


        //方法的作用: 依然是执行
        //记忆一下invoke()-->动态代理有使用
        //invoke:唤醒的意思
        String name = (String) eat1.invoke(dog, "水");
        System.out.println(name);

        //之前是用狗对象调用者写方法,现在是方法追着狗跑,然对象跑它
    }




}
